﻿using System;
using System.Collections.Generic;
using BusinessLogic.Services.Operations;
using EconomicInformationServiceWcf;
using Framework.Exceptions.BusinessExceptions;
using Interfaces.BusinessLogic;
using Interfaces.Enums;
using Interfaces.Infrastructure;
using Interfaces.Models;
using Interfaces.Repositories;
using Interfaces.RepositoryModels.InternalModels.UserRoleModels;
using Interfaces.Validation;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;

namespace BusinessLogicUnitTests
{
    [TestClass]
    public class UserOperationServiceTest
    {
        private Mock<IValidator> _mockValidator;
        private Mock<IUserRepository> _mockUserRepository;
        private Mock<IRoleRepository> _mockRoleRepository;
        private Mock<IHashService> _mockHashService;
        private Mock<IPasswordGeneratedService> _mockPassGenService;
        private Mock<IEmailService> _mockEmailService; 
        private Mock<IEntityMapper<IUser, UserModel>> _inMockEntityMapper;
        private Mock<IEntityMapper<UserModel, IUser>> _outMockEntityMapper;

        private void CreateMockTypes()
        {
            _mockValidator = new Mock<IValidator>();
            _mockUserRepository = new Mock<IUserRepository>();
            _mockRoleRepository = new Mock<IRoleRepository>();
            _mockHashService = new Mock<IHashService>();
            _inMockEntityMapper = new Mock<IEntityMapper<IUser, UserModel>>();
            _outMockEntityMapper = new Mock<IEntityMapper<UserModel, IUser>>();
            _mockPassGenService = new Mock<IPasswordGeneratedService>();
            _mockEmailService = new Mock<IEmailService>();
        }

        private UserOperationService CreateTarget()
        {
            return new UserOperationService(_mockValidator.Object,
                _mockUserRepository.Object,_mockRoleRepository.Object,
                _mockHashService.Object,_inMockEntityMapper.Object,
                _outMockEntityMapper.Object, _mockPassGenService.Object, 
                _mockEmailService.Object);
        }

        [TestInitialize]
        public void TestInitialize()
        {
            Application.Start();
            CreateMockTypes();
        }

        [TestMethod]
        [ExpectedException(typeof(IncompleteArgumentException))]
        public void RomoveUser_EmptyGuid()
        {
            _mockUserRepository.Setup(rep => rep.Delete(It.IsAny<Guid>())).Throws<ArgumentException>();

            var target = CreateTarget();

            target.Remove(Guid.Empty);
        }

        [TestMethod]
        [ExpectedException(typeof(EntityNotExists))]
        public void RemoveRole_RoleNotExist()
        {
            _mockUserRepository.Setup(rep => rep.GetById(It.IsAny<Guid>()))
                               .Returns(new UserModel {Roles = new List<RoleModel>()});
          
            var target = CreateTarget();

            target.RemoveRole(Guid.NewGuid(), RoleType.User);
        }
    }
}
